package cn.slipi.core.component.loadbalance;

import cn.slipi.common.enums.LoadBalanceEnum;
import cn.slipi.common.rule.custom.entity.BalancePiece;
import cn.slipi.common.rule.custom.entity.LoadBalance;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Random;

/**
 * RandomLoadBalanceSelector
 */
public class RandomLoadBalanceSelector implements LoadBalanceSelector {


    @Override
    public BalancePiece select(LoadBalance loadBalance, String ip) {
        Random RANDOM = new Random();
        final BalancePiece[] balancePieces = loadBalance.getData();
        int length = balancePieces.length;
        if (length == 1) {
            return balancePieces[0];
        }
        //根据权重排序才能使用减法原理
        Arrays.stream(balancePieces).sorted(Comparator.comparing(BalancePiece::getWeight));
        int totalWeight = 0;
        boolean sameWeight = true;
        for (int i = 0; i < length; i++) {
            int weight = Integer.parseInt(balancePieces[i].getWeight());
            totalWeight += weight;
            if (sameWeight && i > 0 && weight != Integer.parseInt(balancePieces[i - 1].getWeight())) {
                sameWeight = false;
            }
        }
        if (totalWeight > 0 && !sameWeight) {
            int offset = RANDOM.nextInt(totalWeight);
            for (BalancePiece balancePiece : balancePieces) {
                offset -= Integer.parseInt(balancePiece.getWeight());
                if (offset < 0) {
                    return balancePiece;
                }
            }
        }
        return balancePieces[RANDOM.nextInt(length)];
    }

    @Override
    public String getAlgorithm() {
        return LoadBalanceEnum.RANDOM.getName();
    }
}
